package com.lfy.ch01;


import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Predicate;

/**
 * Collection：包含三大常用（2，3常用） 保存单值
 *    1、Queue
 *    2、List
 *    3、Set
 *
 * Create Retrive Update Delete（增删改查）
 *
 * 单元测试：
 * 1、拎出单个功能，专门为他定义测试方法
 * 2、功能可以通过测试方法运行（而不用main运行，不影响主逻辑）
 * 3、什么时候测试哪个功能，就单独运行哪个方法。
 *
 *
 * 迭代器：
 * 1. 如果有类实现了 Iterable 接口，就必须实现  Iterator<T> iterator(); 方法。
 * 2. 他会返回 Iterator（迭代器）、
 *      1）、hasNext()：判断是否还有下一个元素
 *      2）、next()：返回下一个元素
 *      3）、remove()：删除当前元素；
 *
 */
public class Collection_ListTest {


    @Test
    public void test01(){
        System.out.println("hello....");
    }


    //1、测试 Collection 中的 List 的 各种CRUD方法p
    @Test
    public void testList(){
        //1、创建一个 List 对象; 测试 ArrayList、LinkedList

        // 创建一个 数组方式的 列表。 List 可重复，有序集合。（底层使用数组实现）
        List list = new ArrayList();
        System.out.println("刚new的："+list);

        //2、添加元素
        list.add("1");
        System.out.println("放了一个元素："+list);
        list.add("1");
        System.out.println("放了一个元素："+list);
        list.add("2");
        System.out.println("放了一个元素："+list); // [1, 1, 2] 有序可重复

//        ArrayList aaa = new ArrayList();
//        aaa.add("A");
//        aaa.add("B");

        //快速创建一个 List 并且里面放好元素
        List aaa = List.of("A", "C");

        list.addAll(aaa);
        System.out.println("放了一个aaa集合："+list);


        // 测试 高阶 Add 方法； 指定位置添加元素，并且后面的元素往后移动
        list.add(2,"ABC"); // 1,1,ABC,2,A,C
        System.out.println("指定位置一个元素："+list);
        // index 就是从 0 开始
        list.addAll(3,List.of("D","E")); // 1,1,ABC,D,E,2,A,C
        System.out.println("指定位置放了一个集合："+list);
        list.addFirst("0");
        System.out.println("头部放了一个元素："+list);
        list.addLast("9");
        System.out.println("尾部放了一个元素："+list);


        //2、测试各种 查询
        //2.1） 查询各种其他信息（不查元素）  list.size(); arr.length
        int size = list.size();
        System.out.println("list的长度："+size);

        boolean b = list.contains("ABC");
        System.out.println("是否包含ABC："+b);

        boolean b1 = list.containsAll(List.of("A", "C", "0","L"));
        System.out.println("是否包含所有元素："+b1);

        boolean empty = list.isEmpty();
        System.out.println("是否为空："+empty);

        //2.2）查询元素
        Object o = list.get(3);
        System.out.println("查询指定位置元素："+o);

        Object first = list.getFirst();
        Object last = list.getLast();
        System.out.println("查询首尾元素：首："+first+"  尾："+last);

        //  遍历的三种办法：
        // 方法1：普通for循环；
        //2.3）遍历每一个元素  10； 普通for循环；
        System.out.println("开始遍历");
        for (int i = 0; i < list.size(); i++) {
            Object o1 = list.get(i);
            System.out.print(o1+"\t");
        }
        System.out.println("\n遍历结束");

        //2.4）方法2：增强for循环
        for (Object ele : list){
            System.out.println(ele);
        }

        //2.5）方法3：迭代器


    }


    /**
     * 测试迭代器
     */
    @Test
    public void testIterator(){

        //重点注意： List.of("A","B","C","D","E") 是一个不可变的集合，不能添加元素。
//        List.of("A","B","C","D","E"); //底层也是数组

        // 可读可写;  接口： 依赖导致原则（多态）
        List list = new ArrayList();

        list.addAll(List.of("A","B","C","D","E"));

        //1、获取迭代器
        Iterator iterator = list.iterator();

        //  第一次迭代
        boolean b = iterator.hasNext();
        System.out.println(b);
        Object next = iterator.next();
        System.out.println("元素："+next);


        //  第二次迭代
        b = iterator.hasNext();
        System.out.println(b);
        Object next1 = iterator.next();
        System.out.println("元素："+next1);

        //  第三次迭代
        Object next2 = iterator.next();
        System.out.println("元素："+next2);

        //  第四次迭代. 安全期间，每次迭代前，先判断是否有下一个元素。
        Object next3 = iterator.next();
        System.out.println("元素："+next3);


        System.out.println("====================");
        //使用迭代器进行遍历; 只要有下一个，就拿出这个元素，否则结束。
        Iterator iterator1 = list.iterator();

        // 集合涉及到边遍历，边删除，这些就用迭代器，如果只是查，就直接 增强for
        // while 适合 没有固定次数的循环。 JCP
        while (iterator1.hasNext()){
            // 迭代器会继续自动往后移动，直到没有下一个元素。
            Object next4 = iterator1.next();
            if("C".equals(next4)){
                iterator1.remove();
            }
            System.out.println("元素~~~："+next4);
        }
        System.out.println(list);



    }


    /**
     * 测试删除和更新
     */
    @Test
    public void testRemoveUpdate(){
        List list = new LinkedList();
        list.addAll(List.of("A","B","C","D","E","A"));
        System.out.println(list);

        list.set(2, "雷");
        System.out.println(list);


        boolean lei = list.remove("雷");
        System.out.println("是否删除成功："+lei);

        boolean x = list.remove("X");
        System.out.println(x);



        //1、删除 指定的所有元素
//        boolean b = list.removeAll(List.of("A", "B", "E", "哈哈"));
//        System.out.println(b);
//        System.out.println(list);



        //2、 删除除了 指定的所有元素; 留下指定的元素。
//        boolean b = list.retainAll(List.of("A", "B", "E"));
//        System.out.println(b);
//        System.out.println(list);



        //匿名内部类写法
        Predicate  predicate = new Predicate() {
            @Override
            public boolean test(Object o) {
                if (o.equals("A")) {
                    return true;
                }
                return false;
            }
        };

        // Predicate：断言； 删除满足条件的元素。
        boolean b1 = list.removeIf(predicate);
        System.out.println(b1);
        System.out.println(list);


    }
}
